Skip to content

fix(dock): debounce tray plugin list logging to ensure stable state#1597

Open
Ivy233 wants to merge 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/debounce-plugin-log
Open

fix(dock): debounce tray plugin list logging to ensure stable state#1597
Ivy233 wants to merge 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/debounce-plugin-log

Conversation

@Ivy233
Copy link
Copy Markdown
Contributor

@Ivy233 Ivy233 commented May 14, 2026

Replace fixed 3-second delay with debounce mechanism for tray plugin list event logging. The original approach reported plugin state immediately upon tray applet connection and again after a fixed 3-second delay, which could capture incomplete plugin lists during login.

Use a 2-second debounce timer that resets on each
pluginsChanged signal, ensuring the log only records the final stable plugin list. Also adjust dde-application- manager packaging dependencies.

将托盘插件列表事件上报从固定3秒延迟改为防抖机制。
原始方案在托盘小程序连接后立即上报并延迟3秒再报一次,
在登录时可能捕获到不完整的插件列表。
改用2秒防抖定时器,每次插件列表变化时重置,
确保只记录最终稳定的插件列表。同时调整
dde-application-manager 打包依赖。

PMS: BUG-361067

PS: 打包依赖是dde-am修改的时候,依赖调整,如果需要单独提pr就comment一下。调整pr原因:
版本号来源:linuxdeepin/dde-application-manager#354
依赖修改对应pr:#1590

Summary by Sourcery

Debounce logging of the dock tray plugin list so it records only the final stable state after plugin changes.

Bug Fixes:

  • Avoid logging incomplete tray plugin lists during startup by deferring logging until the plugin state stabilizes.

Enhancements:

  • Introduce a reusable debounced timer in the dock DBus proxy to trigger delayed plugin state logging instead of a fixed single-shot delay.

Build:

  • Adjust dde-application-manager packaging dependencies in the Debian control file.

@Ivy233 Ivy233 requested review from 18202781743, BLumia and mhduiy May 14, 2026 13:31
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Ivy233

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 14, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Replaces the fixed 3‑second delayed logging of tray plugin lists with a debounced logging mechanism triggered by plugin change events, and adjusts dde-application-manager packaging dependencies.

Sequence diagram for debounced tray plugin list logging

sequenceDiagram
    participant TrayApplet
    participant DockDBusProxy
    participant DebounceTimer

    TrayApplet->>DockDBusProxy: pluginsChanged()
    DockDBusProxy->>DockDBusProxy: scheduleDebouncedLog()
    alt first_call_or_timer_not_created
        DockDBusProxy->>DebounceTimer: create QTimer
        DockDBusProxy->>DebounceTimer: setSingleShot(true)
        DockDBusProxy->>DebounceTimer: setInterval(2000)
        DebounceTimer-->>DockDBusProxy: timeout (connected to logInitialPluginState)
    end
    DockDBusProxy->>DebounceTimer: start()

    rect rgb(230,230,230)
        Note over DebounceTimer: 2s debounce window
    end

    DebounceTimer-->>DockDBusProxy: timeout
    DockDBusProxy->>DockDBusProxy: logInitialPluginState()
Loading

File-Level Changes

Change Details Files
Refactor tray plugin list logging from a fixed single-shot delay to an event-driven debounce timer to capture a stable plugin set.
  • Remove the post-init QTimer::singleShot(3000, ...) call that invoked logInitialPluginState after a fixed delay.
  • Connect the tray applet's pluginsChanged signal to the DockDBusProxy::pluginsChanged signal and then to a new lambda that schedules debounced logging.
  • Trigger an initial debounced logging schedule once the tray applet connects, instead of logging immediately plus a delayed second time.
panels/dock/dockdbusproxy.cpp
Introduce a reusable debounced logging helper that delays logInitialPluginState until plugins have been stable for 2 seconds.
  • Add a scheduleDebouncedLog() method that lazily creates a single-shot QTimer with a 2-second interval and connects its timeout to logInitialPluginState.
  • Start or restart the debounce timer on each scheduleDebouncedLog() call so rapid pluginsChanged bursts coalesce into a single log.
  • Declare scheduleDebouncedLog() and a QTimer* m_debounceTimer member initialized to nullptr in DockDBusProxy.
panels/dock/dockdbusproxy.cpp
panels/dock/dockdbusproxy.h
Update Debian packaging to adjust dde-application-manager dependencies.
  • Modify the dde-application-manager dependency list to reflect the dock changes and ensure correct runtime/build requirements.
debian/control

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider extracting the hardcoded 2000 ms debounce interval into a named constant or configuration value so the debounce behavior is easier to adjust and understand in the future.
  • The QTimer timeout connection in scheduleDebouncedLog uses a lambda that simply calls logInitialPluginState; replacing this with a direct slot connection would simplify the code and avoid an extra indirection.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the hardcoded 2000 ms debounce interval into a named constant or configuration value so the debounce behavior is easier to adjust and understand in the future.
- The QTimer timeout connection in `scheduleDebouncedLog` uses a lambda that simply calls `logInitialPluginState`; replacing this with a direct slot connection would simplify the code and avoid an extra indirection.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Ivy233 Ivy233 force-pushed the fix/debounce-plugin-log branch from 248ac3d to f8b4b72 Compare May 14, 2026 13:44
Comment thread panels/dock/dockdbusproxy.cpp Outdated
Comment thread panels/dock/dockdbusproxy.cpp
Replace fixed 3-second delay with debounce mechanism for
tray plugin list event logging. The original approach
reported plugin state immediately upon tray applet
connection and again after a fixed 3-second delay, which
could capture incomplete plugin lists during login.

Use a 2-second debounce timer that resets on each
pluginsChanged signal, ensuring the log only records
the final stable plugin list. Also adjust dde-application-
manager packaging dependencies.

将托盘插件列表事件上报从固定3秒延迟改为防抖机制。
原始方案在托盘小程序连接后立即上报并延迟3秒再报一次,
在登录时可能捕获到不完整的插件列表。
改用2秒防抖定时器,每次插件列表变化时重置,
确保只记录最终稳定的插件列表。同时调整
dde-application-manager 打包依赖。

PMS: BUG-361067
@Ivy233 Ivy233 force-pushed the fix/debounce-plugin-log branch from f8b4b72 to 2e5d44d Compare May 16, 2026 08:03
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的 Git Diff,本次修改主要涉及 Debian 打包依赖版本调整,以及 Dock 插件状态日志记录的防抖逻辑重构。

总体来说,这次修改将原本的固定延时日志记录改为了基于事件驱动的防抖逻辑,这是一个很好的优化,可以避免在插件频繁变动时产生冗余日志。但在依赖版本管理、Qt 内存与对象生命周期管理以及代码健壮性方面,我有一些改进建议。

以下是详细的审查意见:

1. 语法与逻辑

1.1 依赖版本运算符不一致(Debian Control)

  • 问题:在 debian/control 中,Build-Dependsdde-application-manager-api>> 1.2.51 改为了 >= 1.2.48,而 Depends 中新增了 dde-application-manager (>> 1.2.51)。同时,文件中其他依赖使用了 >>>(如 dde-api-dev (>> 6.0.39)dde-tray-loader-dev (> 2.0.24))。
  • 风险:Debian 控制文件中 >>> 在语义上有细微差别,混用会导致维护困难且容易引发依赖解析歧义。另外,编译依赖 (>= 1.2.48) 和运行依赖 (>> 1.2.51) 的版本基线不同,如果运行时必须大于 1.2.51,那么编译时允许 1.2.48-1.2.51 可能会导致编译通过但运行时依赖不满足的问题。
  • 建议:统一版本运算符(Debian 推荐使用 >=>> 时保持项目内一致),并确保 Build-Depends 的最低版本不应低于 Depends 的最低版本要求。建议将 Depends 中的 >> 也改为 >=,并评估是否需要统一版本号。

1.2 首次加载的立即触发逻辑存在隐患

  • 问题:在 dockdbusproxy.cpp 中,注释写着 // Trigger a debounced log on each change, and also schedule one immediately after first load,然后直接调用了 scheduleDebouncedLog()。虽然这会启动 2 秒的定时器,但如果开发者本意是“首次加载时立即打印一次日志,后续变动再防抖”,那么当前逻辑并未实现“立即”。
  • 建议:如果首次加载需要立即记录,应改为:
    logInitialPluginState(); // 立即记录首次状态
    scheduleDebouncedLog();  // 后续变动防抖(此处也可以省略,除非首次加载后2秒内必定会变动)
    如果当前逻辑(首次加载也延迟2秒记录)是符合预期的,建议修改注释,去掉 "schedule one immediately",以免误导。

2. 代码质量

2.1 对象生命周期与内存管理

  • 问题:在 scheduleDebouncedLog() 中,使用了 new QTimer(this),并在头文件中声明了 QTimer *m_debounceTimer = nullptr;。虽然传入 this 作为 parent 确保了对象会被自动销毁,但在 Qt 中,如果该函数被多次调用(虽然当前有 if (!m_debounceTimer) 的保护),成员指针加 new 的模式容易在后续迭代中引发双重释放或悬空指针问题。
  • 建议:更 Qt 且更现代的做法是使用 QPointer 或直接在类的构造函数中初始化定长 Timer,而不是在运行时延迟分配。考虑到这个 Timer 生命周期与 DockDBusProxy 完全一致,建议直接在构造函数中初始化。

2.2 代码封装与复用

  • 问题scheduleDebouncedLogconnect 的 Lambda 表达式仅仅是对 logInitialPluginState() 的一层包装。
  • 建议:可以直接连接到目标函数,减少 Lambda 带来的闭包开销和代码冗余。

3. 代码性能

3.1 信号连接的冗余

  • 问题:每次 m_trayApplet 触发 pluginsChanged 时,都会经过 DockDBusProxy::pluginsChanged 信号转发,然后触发 scheduleDebouncedLog(),重新调用 m_debounceTimer->start()。频繁的信号槽调用和重启定时器在极端情况下(如1秒内触发数十次变动)会有微小的性能开销。
  • 建议:当前防抖逻辑已经很好地规避了高频触发导致的 logInitialPluginState 高频执行,性能瓶颈已解除。上述信号转发的开销在 Qt 事件循环中微乎其微,可接受。无需特别修改,仅作说明。

4. 代码安全

4.1 日志注入与敏感信息泄露

  • 问题:虽然 Diff 中未展示 logInitialPluginState() 的内部实现,但涉及“插件列表”的日志记录,往往容易记录到用户自定义路径下的插件名称或路径。
  • 建议:请确保 logInitialPluginState() 内部对插件名称、路径等外部数据进行了清洗或转义,防止日志伪造攻击,同时避免在日志中输出包含用户主目录的绝对路径等隐私信息。

💡 综合改进后的代码建议

基于以上分析,我为你重构了 C++ 部分的代码,使其更符合 Qt 的最佳实践,逻辑更清晰:

panels/dock/dockdbusproxy.h 修改:

 // Debounce timer to ensure the plugin list has stabilized before logging
-QTimer *m_debounceTimer = nullptr;
+QTimer m_debounceTimer; // 直接使用对象,避免堆分配和指针管理

panels/dock/dockdbusproxy.cpp 修改:

  1. 构造函数初始化列表中增加(如果有的话):
DockDBusProxy::DockDBusProxy(DockPanel* parent)
    : QObject(parent)
    , m_debounceTimer()
{
    // 设置单次触发和防抖间隔
    m_debounceTimer.setSingleShot(true);
    m_debounceTimer.setInterval(2000);
    // 直接连接到目标函数,无需Lambda包装
    connect(&m_debounceTimer, &QTimer::timeout, this, &DockDBusProxy::logInitialPluginState);
    
    // ... 原有其他初始化代码 ...
}
  1. Lambda 和首次加载逻辑优化:
         connect(m_trayApplet, SIGNAL(pluginsChanged()), this, SIGNAL(pluginsChanged()));
-        // Trigger a debounced log on each change, and also schedule one immediately after first load
-        connect(this, &DockDBusProxy::pluginsChanged, this, &DockDBusProxy::scheduleDebouncedLog);
-        scheduleDebouncedLog();
+        // 当插件列表发生变化时,重置防抖定时器
+        connect(this, &DockDBusProxy::pluginsChanged, this, [this]() {
+            m_debounceTimer.start(); 
+        });
+        // 首次加载完成后,启动防抖定时器(2秒后若无变动则记录日志)
+        m_debounceTimer.start();
     }
 });
  1. 删除 scheduleDebouncedLog() 函数的实现(已内联到构造和连接中,若希望保留函数接口以增加额外逻辑,可保留,但内部改为 m_debounceTimer.start();)。

Debian Control 修改建议:

- dde-application-manager-api (>= 1.2.48),
+ dde-application-manager-api (>= 1.2.51), # 与运行时依赖保持一致
  dde-api-dev (>> 6.0.39),
  dde-tray-loader-dev (> 2.0.24),
  extra-cmake-modules,
---
- dde-application-manager (>> 1.2.51),
+ dde-application-manager (>= 1.2.51), # 统一使用 >= 运算符
  ${misc:Depends},

@Ivy233 Ivy233 requested a review from mhduiy May 16, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants